MySQL レプリケーション
#MySQL #DB
https://scrapbox.io/files/6389bdf8dd159e001d1af29e.png
MySQLにおけるレプリケーションの仕組みについて理解しておこうと思う。
レプリケーションの流れ
1. マスタで処理された更新系のクエリが逐次、バイナリログに記録される
2. スレーブのI/OスレッドがマスターのBinlog Dumpスレッドに接続する
3. マスターのBinlog Dumpスレッドは、バイナリログの内容をスレーブにどんどん送信する
4. スレーブのI/Oスレッドは、受け取ったバイナリログの内容ををリレーログに保存する
5. スレーブのSQLスレッドは、リレーログからクエリを読み取って実行する
レプリケーション時に活躍するメンバ
I/Oスレッド
マスターのBinlog Dumpスレッドから得たバイナリログをひたすらリレーログ(relay log)に記録する。
スレーブ上にあるスレッド。
SQLスレッド
リレーログにあるクエリをひたすら実行していく。
スレーブ上にあるスレッド。
Binlog Dumpスレッド
Binlogの内容を読み取ってスレーブ側に送る。
マスター上にあるスレッド。
master.info
マスタのホスト名、接続ユーザ名、マスタのバイナリログのファイル名とスレーブのI/Oスレッドがどこまでマスタのバイナリログを取得したかなどが記録され、I/Oスレッドによって更新されます。これはスレーブがレプリケーションを再開する際に、どこまでマスタのバイナリログを処理したか確認するために使われます。
なるほど、バイナリログを読んでくるたびにmaster.infoをI/Oスレッドが更新してるんだな。
レプリケーション再開示に、途中まで読んだバイナリログから再開するのね。
relay-log.info
リレーログのファイル名や位置情報などが記録され、SQLスレッドによって更新されます。master.infoと同じく、レプリケーションを再開する際に、リレーログをどこまで処理したか確認するために使われます。
リレーログのどこまでを実行してデータに反映したかってのがわかるのね。
そしてSQLスレッドがこのファイルを更新してると。なるほど。
バイナリログ
データ更新に関するクエリがひたすら記録されてるログ。
参照系は記録されない。
レプリケーションの他にも、フルバックアップからの更新分のみのバックアップという用途にも使われます。
MySQL バイナリログ
リレーログ
スレーブのI/Oスレッドがマスタのバイナリログをスレーブ側に保存したものです。ですのでその内容はバイナリログと同じです。
リレーログに関しては必要がなくなったら、SQLスレッドによって自動的に削除される。
基本的には、反映が終わり次第ファイル単位で削除されるらしい
なぜスレーブ側には2つのスレッドがあるのか
SQLスレッドなど必要なく、I/OスレッドでBinlog読み取りとクエリ実行両方を行えばいいのでは?
a.icon以下
実はMySQL 3.23のレプリケーションでは、スレーブでは1つのスレッドしかなく、データの取得と実行の両方を行っていました。この場合、データの取得→実行→取得…というように交互に処理されるため、時間のかかるクエリをスレーブで実行している間はマスタからのデータの取得が停止してしまい、結果的にマスタに追い付くのに時間がかかってしまいます。
また、マスタから得たデータをスレーブ内にリレーログとして一旦、保存することにより、スレーブのSQLスレッドの処理が遅れている間にマスタがダウンしたとしても、I/Oスレッドがマスタがダウンする直前までのデータをリレーログとしてローカルに保存しているので、暫く待てばスレーブはマスタがダウンする直前と同じデータを持つ状態になります。
要するに以下2点
1. レプリケーションの同期スピードを上げるため
2. マスター側で障害があっても、スレーブが独立して同期しやすい状態を保つため
レプリケーション構成のセットアップ方法
大まかな流れ
1. マスター側でレプリケーション用(スレーブにバイナリログ送る用)ユーザーを作成し、REPLICATION権限を付与
2. マスター側でバイナリロギングを有効化する(cf. MySQL バイナリログ#63d31c09b3641f00007a7559)
3. マスター側でロックなどを取って、書き込みを止める
FLUSH TABLES WITH READ LOCK;
4. マスター側でデータをダンプなどして取得する
5. マスター側でSHOW MASTER STATUS;を実行して、現時点のバイナリログファイル名と書き込みポジションを記憶する
6. マスター側でロック解除などして書き込みを再開する
7. スレーブ側で「4.」で取得したデータを復旧する
8. スレーブ側でマスター情報を入力して連携する
9. スレーブ側でレプリケーションを開始する
参考:
MySQLでレプリケーション設定 - Qiita
よくあるトラブル
リレーログがめちゃくちゃ溜まってしまう
a.icon SQLスレッドが止まってるが、I/Oスレッドが動き続けてる際に起こる問題
SQLスレッドはリレーログを削除する役割もあるが、それが止まることにより、永遠にI/Oスレッドによるリレーログ書き込みが増え続ける。
スレーブのリレーログが増殖してサーバのディスクを圧迫した - Road To Nowhere
参考
スレーブのリレーログが増殖してサーバのディスクを圧迫した - Road To Nowhere